﻿package org.dicker.util;

import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;

public class DBUtil_v3 {

	private static final Logger logger = Logger.getLogger(DBUtil_v3.class);
	
	/*
	 * 数据库连接属性 
	 */
	//驱动类名
	private static final String DRIVER_NAME="com.mysql.jdbc.Driver";
	//url
	private static final String URL="jdbc:mysql://127.0.0.1:3306/big-birds?useUnicode=true&characterEncoding=utf8";
	//username
	private static final String USERNAME="root";
	//password
	private static final String PASSWORD="root";
	
//	// 驱动类名
//	private static final String DRIVER_NAME = "oracle.jdbc.driver.OracleDriver";
//	// url
//	private static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
//	// username
//	private static final String USERNAME = "scott";
//	// password
//	private static final String PASSWORD = "tiger";
	

	private Connection conn = null;
	private PreparedStatement stmt = null;
	private ResultSet rs = null;

	static {
		try {
			// 1>加载驱动（数据库产商提供的驱动）
			Class.forName(DRIVER_NAME);
		} catch (ClassNotFoundException e) {
	        logger.error(GlobleUtil.exceptionConvertToString(e));
		}
	}

	//打开连接
	private void open() throws SQLException{
		// 2>创建jdbc连接
		// 连接mysql中yunhe02数据库
		conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
		// 连接mysql中yunhe03数据库

		// 连接oracle数据库
	}

	/**
	 * 执行DQL
	 * 
	 * @throws SQLException
	 */
	public List<Map<String, Object>> executeDQL(String sql, Object... paramList) {
		List<Map<String, Object>> list=new ArrayList<Map<String,Object>>();
		
		try {
			open();
			stmt = conn.prepareStatement(sql);
			
			logger.debug("执行的SQL语句是>>>>>>"+sql);
			logger.debug("填充SQL的参数是>>>>>>");
			if (paramList!=null) {
				// 3.1>填充参数(参数个数？，参数类型？)
				for (int i = 0; i < paramList.length; i++) {
					stmt.setObject(i + 1, paramList[i]);
					logger.debug(paramList[i]+",");
				}
			}
			// 4>执行DML语句
			rs = stmt.executeQuery();
			
			while (rs.next()) {//每次循环读取“一行记录”
				Map<String, Object> mapObj=new HashMap<String, Object>();
				
				/*
				 * 解析结果集，赋值给mapObj
				 */
				//获取结果集中的结构信息（包括字段名、字段总数量）
				
				ResultSetMetaData metaData=rs.getMetaData();
				//获取“字段总数量”
				int columnCount=metaData.getColumnCount();
				for (int i = 1; i <= columnCount; i++) {
					//metaData.getColumnName(i)  取出对应第几列的“列名”
					//>mysql取出的列名是小写字母
					//>oracle取出的列名是大写字母
					//*****数据库是不区分大小写，而java是区分大小写。所以为了保证统一性，统一将取出来的列名转换大写/小写*****
					
					Object valueObj=rs.getObject(i);
					
//					if (valueObj instanceof BigDecimal) {
//						//把BigDecimal类型统一转成了Integer
//						//如果是double呢？
//						//解决方案：
//						//如果实体类中对应的属性类型是int，那就转Integer
//						//如果实体类中对应的属性类型是double，那就转Double
//						valueObj=((BigDecimal) valueObj).intValue();
//					}
					
					//metaData.getColumnName(i)  	只能取列名
					//metaData.getColumnLabel(i)	有别名优先别名，其次才是考虑列名
					mapObj.put(metaData.getColumnLabel(i).toLowerCase(),valueObj);
					//mapObj.put(metaData.getColumnName(i).toLowerCase(),valueObj);
					
					//mapObj.put("字段名", rs.getObject("字段名/下标"));
					
					/*
					 * rs.getObject(i)；
					 * 编译时类型是Object，而运行时类型取决于数据库中对应的那个字段的类型
					 * 
					 * MySQL：
					 * int				-》	java中的Integer
					 * double			-》	java中的Double
					 * decimal			-》	java中的BigDecimal
					 * char				-》	java中的String
					 * varchar、text		-》	java中的String
					 * datetime			-》	java中的"java.sql.Date"
					 * 
					 * 
					 * Oracle：
					 * number					-》	java中的BigDecimal
					 * char						-》	java中的String
					 * varchar2、nvarchar2		-》	java中的String
					 * datetime					-》	java中的"java.sql.Date"
					 */
					
				}
				
				
				list.add(mapObj);	
			}
			
		} catch (SQLException e) {
			logger.error(GlobleUtil.exceptionConvertToString(e));
		}finally{
			close();
		}

		return list;// 返回的是解析结果集过后的“List集合”

	}

	/**
	 * 执行DML
	 * 
	 * @throws SQLException
	 */
	public int executeDML(String sql, Object... paramList) {
		
		// 4>执行DML语句
		int result=0;
		try {
			open();
			// 3>创建Statement对象
			stmt = conn.prepareStatement(sql);
			
			logger.debug("执行的SQL语句是>>>>>>"+sql);
			logger.debug("填充SQL的参数是>>>>>>");
			if (paramList!=null) {
				// 3.1>填充参数(参数个数？，参数类型？)
				for (int i = 0; i < paramList.length; i++) {
					stmt.setObject(i +1, paramList[i]);
					logger.debug(paramList[i]+",");
				}
			}
			
			result = stmt.executeUpdate();
		} catch (SQLException e) {
			logger.error(GlobleUtil.exceptionConvertToString(e));
		} finally{
			close();
		}

		return result;
	}

	//释放资源
	private void close() {
		try {
			if (rs != null) {
				rs.close();
			}
			if (stmt != null) {
				stmt.close();
			}
			if (conn != null) {
				conn.close();
			}

		} catch (SQLException e) {
			logger.error(GlobleUtil.exceptionConvertToString(e));
		}
	}

}
